package ipc;

import java.util.HashMap;

import org.omg.CORBA._IDLTypeStub;

import rddl.State;
import rddl.RDDL.PVAR_NAME;

class myDD{
	public HashMap<Integer, String> _ID2var;
	public HashMap<Integer, Integer> _ID2high;
	public HashMap<Integer, Integer> _ID2low;
	private int _rootID;
	
	public myDD(){
		_ID2var = new HashMap<Integer, String>();
		_ID2high = new HashMap<Integer, Integer>();
		_ID2low = new HashMap<Integer, Integer>();
		_rootID = -1;
	}
	
	public void addNode(Integer ID, String gfluent){
		//TODO: read in leaves with range of values
		_ID2var.put(ID, gfluent);
		if( _rootID == -1 ) _rootID = ID.intValue();
	}
	
	public void addEdge(Integer src, Integer dest, boolean thetruth){
		if(thetruth)
			_ID2high.put(src, dest);
		else
			_ID2low.put(src, dest);
	}
	
	public String toString(){
		return _ID2var.toString() + "\nHIGH " + _ID2high.toString() + "\nLOW " + _ID2low.toString();
	}
	
	public boolean isLeaf(int id){
		if( _ID2high.get(id) == null && _ID2low.get(id) == null )
			return true;
		return false;
	}
	
	public String walk(HashMap<String, Boolean> state){
	
		//System.err.println(_ID2var.toString());
		//System.err.println(_ID2high.toString());
		//System.err.println(_ID2low.toString());
	
		int cur = _rootID;
		while( !isLeaf(cur) ){
			String name = _ID2var.get(cur);
			Boolean value = state.get(name);
			if( value == null ){
				Main.exceptionLog.log(state.toString());
				Main.exceptionLog.log(name);
				Main.exceptionLog.log("Could not find " + name + "in " + state.toString() + " " );
				return null;
			}

			if( value.booleanValue()  == true ) cur = _ID2high.get(cur);
			else cur = _ID2low.get(cur);
		}
		String ret = _ID2var.get(cur);
		if( ret == null ) {
			Main.exceptionLog.log("Query failed " + ret + " " + cur );
		}
		return ret;
	}

	public	double getRange(){
		double min = Double.POSITIVE_INFINITY;
		double max = Double.NEGATIVE_INFINITY;

		for( String s : _ID2var.values() ){
			String s2 = s.trim();
			if( s2.indexOf(" ") == -1 )
				continue;
			String[] s3 = s2.split("\\s+");
			for( int i = 0 ; i < s3.length; ++i ){
 				try{
					double d = Double.parseDouble(s3[i]);
					if(d > max) max = d;
					if(d < min) min = d; 
				}catch(Exception e){}			
			}
		}
//		System.err.println("Range "+Math.abs(max-min));
		return Math.abs(max-min);
	}
}
